﻿using System;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;

namespace YArchitech.HVAC
{
	public class PositivePipe<T> where T : MEPCurve
	{
		public bool IsInLeft { get; set; }

		public bool IsInRight { get; set; }

		public bool IsGrouped { get; set; }

		public XYZ StartPoint { get; set; }

		public XYZ EndPoint { get; set; }

		public XYZ Vector { get; set; }

		public PositivePipe(T wrappedPipe)
		{
			this.pipe = wrappedPipe;
			this.IsInLeft = false;
			this.IsInRight = false;
			this.IsGrouped = false;
			this.UnifyPipeDirection();
		}

		protected bool UnifyPipeDirection()
		{
			bool result = false;
			if (this.pipe != null)
			{
				YJKCurve hycurve = new YJKCurve((this.pipe.Location as LocationCurve).Curve);
				this.StartPoint = new XYZ(hycurve.StartPoint.X, hycurve.StartPoint.Y, 0.0);
				this.EndPoint = new XYZ(hycurve.EndPoint.X, hycurve.EndPoint.Y, 0.0);
				if (this.StartPoint.X > this.EndPoint.X)
				{
					XYZ startPoint = this.StartPoint;
					this.StartPoint = this.EndPoint;
					this.EndPoint = startPoint;
				}
				if (PositivePipe<T>.IsEqual(this.StartPoint.X, this.EndPoint.X) && PositivePipe<T>.GreaterThan(this.StartPoint.Y, this.EndPoint.Y))
				{
					XYZ startPoint2 = this.StartPoint;
					this.StartPoint = this.EndPoint;
					this.EndPoint = startPoint2;
				}
				this.Vector = (this.EndPoint - this.StartPoint).Normalize();
			}
			return result;
		}

		public Line GetNormalVecLine()
		{
			XYZ xyz = this.EndPoint - this.StartPoint;
			XYZ midllePoint = this.GetMidllePoint(this.StartPoint, this.EndPoint);
			XYZ xyz2 = new XYZ(0.0, 0.0, 1.0).CrossProduct(xyz);
			XYZ endPoint = midllePoint.Add(xyz2);
			return YJKLineEx.YJKGetBound(midllePoint, endPoint);
		}

		public ElementId GetSystemElementId()
		{
			Parameter parameter = null;
			if (this.pipe is Pipe)
			{
				parameter = this.pipe.get_Parameter(BuiltInParameter.RBS_PIPING_SYSTEM_TYPE_PARAM);
			}
			if (parameter != null)
			{
				return parameter.AsElementId();
			}
			return null;
		}

		public PositionType GetPositionType(XYZ point)
		{
			double val = this.StartPoint.DistanceTo(point);
			double val2 = this.EndPoint.DistanceTo(point);
			if (PositivePipe<T>.LessThan(val, val2))
			{
				return PositionType.StartNode;
			}
			if (PositivePipe<T>.GreaterThan(val, val2))
			{
				return PositionType.EndNode;
			}
			return PositionType.OtherPoint;
		}

		protected XYZ GetMidllePoint(XYZ startPt, XYZ endPt)
		{
			XYZ xyz = endPt - startPt;
			return startPt + xyz / 2.0;
		}

		public static bool GreaterThan(double val1, double val2)
		{
			return val1 - val2 > 1E-09;
		}

		public static bool IsEqual(double val1, double val2)
		{
			return !PositivePipe<T>.LessThan(val1, val2) && !PositivePipe<T>.LessThan(val2, val1);
		}

		public static bool LessThan(double val1, double val2)
		{
			return val1 - val2 < -1E-09;
		}

		public T pipe;

		public const double _epsDouble = 1E-09;

		public XYZ intersection;
	}
}
